perm filename RLISP.ACH[UP,DOC]3 blob sn#245542 filedate 1976-11-06 generic text, type T, neo UTF8
UTAH COMPUTATIONAL PHYSICS GROUP		     October 1974
OPERATING NOTE NO. 5.1



















			 R E D U C E   2 

		    S Y M B O L I C   M O D E 

			   P R I M E R*


			       by


		       Anthony  C.  Hearn
		       University of Utah
















*Work supported in part by  the  National  Science  Foundation  under
Grant No. GJ-32181 and by the Advanced Research  Projects  Agency  of
the   Office   of  the  Department  of  Defense  under  Contract  No.
DAHC15-73-C-0363.
                                  2                                  


1. INTRODUCTION

	REDUCE  is a program designed primarily for general algebraic
computations of interest to mathematicians, physicists and engineers.
However,  its  source  language is general enough to allow for a full
range of LISP-like symbolic calculations.  This  primer  is  a  brief
guide  to  this  source language.  It does not describe the algebraic
capabilities of the system, so  anyone  interested  in  these  should
consult  the  REDUCE  2 User's Manual [1], of which this primer is an
extract.

	This  primer  assumes  that  the  reader  has  a   reasonable
acquaintance  with LISP 1.5 at the level of the LISP 1.5 Programmer's
Manual [2] or Clark Weissman's LISP 1.5 Primer[3]. Anyone  unfamiliar
with this material is advised to study it before proceeding further.

	In Section 2 of this primer, we give  details  of  the  basic
structure  of  REDUCE programs. In Section 3, a list of the functions
available in the system is given, and finally in Section 4  a  syntax
definition of a subset of REDUCE is given.

	The  author  would  appreciate  hearing  from  any  users who
experience trouble with the system (please include copies of relevant
input and output).

                                  3                                  


2. STRUCTURE OF PROGRAMS


2.1 Preliminary

	A REDUCE program consists of a  set  of  functional  commands
which  are evaluated sequentially by the computer. These commands are
built  up  from  declarations,  statements  and  expressions.    Such
entities  are composed of sequences of numbers, variables, operators,
strings,  reserved  words  and  delimiters  (such   as   commas   and
parentheses), which in turn are sequences of basic characters.


2.2  The REDUCE Standard Character Set

The basic characters which are used to build up  REDUCE  symbols  are
the following:

i)   The 26 upper case letters A through Z
ii)  The 10 decimal digits 0 through 9
iii) The special characters ! " $ % ' ( ) * + , - . / : ; < > = <blank>

Programs composed from this standard set of characters  will  run  in
any available REDUCE system.  In addition, several implementations of
REDUCE (for example, on the  PDP-10)  use  additional  characters  to
represent  some  of the operators in the system.  The local operating
instructions for the given  computer  should  be  consulted  for  the
meaning  of  these  special  characters.  However,  for generality in
exposition we shall limit ourselves to the standard character set  in
the body of this manual.


2.3 Numbers

	Numbers in REDUCE may be of  two  types;  integer  and  real.
Integers  consist  of a signed or unsigned sequence of decimal digits
written without a decimal point.

	e. g.  -2, 5396, +32

Real numbers may be written in two ways;

i)   as a signed or unsigned sequence of 1-9 decimal digits with
     an embedded decimal point.

ii)  as in i) followed by a decimal exponent which is written as
     the letter E followed by a signed or unsigned integer.

e. g. 32.  +32.0 0.32E2 and 320.E-1  are all representations of 32.

Restriction:

The unsigned part of any number may NOT begin with a decimal point.
                                  4                                  


	i. e. NOT ALLOWED  .5  -.23  +.12


2.4 Identifiers

	Identifiers   in   REDUCE   consist  of  one  to  twenty-four
alphanumeric  characters  (i.e.  upper  case  alphabetic  letters  or
decimal digits) the first of which must be alphabetic.

	e. g.  A AZ P1 Q23P  AVERYLONGVARIABLE  

	It is also possible to include non-alphanumeric characters in
identifiers by prefixing the character by an exclamation mark.

	e. g., DSK!: GET!*!* A!+B

Identifiers are used as variables,  labels  and  to  name  operators,
arrays and procedures.

Restrictions:

Reserved words in REDUCE (see  Section  2.10)  may  not  be  used  as
identifiers.  No  spaces  may  appear  within  an  identifier, and an
identifier may not extend over a line of text.


2.5 Variables

	Variables are  a  particular  type  of  identifier,  and  are
specified   by   name   and  type.    Their  names  must  be  allowed
identifiers.   There are several variable types  allowed,  and  these
are discussed later in Section 2.12.1.


2.6 Operators

	Operators in REDUCE are also  specified  by  name  and  type.
There are two types, infix and prefix.

Infix operators occur between their arguments.

	e. g. A + B - C
	      U . V

The following infix operators are built into the system.

<infix operator> ::= :=|OR|AND|NOT|MEMBER|=|NEQ|EQ|>=|>|<=|<|+|-|*|/|**|.

	These operators may be further divided into the following sub
classes

   <assignment operator> ::= :=
   <logical operator>    ::= OR|AND|NOT|MEMBER
   <relational operator> ::= =|EQ|NEQ|>=|>|<=|<
                                  5                                  


   <arithmetic operator> ::= +|-|*|/|**
   <symbolic operator>   ::= .

	For compatibility with  the  intermediate  language  used  by
REDUCE,  each  special  character  infix  operator  has an additional
alphanumeric identifier associated with it.   These  identifiers  may
be  used  interchangably with the corresponding infix character(s) on
input.  This correspondence is as follows:

        :=      SETQ
	=	EQUAL
	>=	GEQ
	>	GREATERP
	<=	LEQ
	<	LESSP
	+	PLUS
	-	DIFFERENCE (unary MINUS)
	*	TIMES
	/	QUOTIENT (unary RECIP)
        **      EXPT
	.	CONS


The above operators are assumed to be binary,  except  NOT  which  is
unary and + and * which are nary. In addition, - and / may be used in
a unary position. Any other operator is parsed as a  binary  operator
using  a  left  procedure  grouping.   Thus  A/B/C  is interpreted as
(A/B)/C. There are two exceptions to this latter rule, namely :=  and
.  which  have  a  right  precedence  grouping.  Thus  A  .  B . C is
interpreted as A . (B . C).

Parentheses may be used to specify  the  order  of  combination.   If
parentheses are omitted then this order is by the precedence ordering
given by the above list. I. e., := has the lowest  precedence  and  .
the highest.

	Prefix operators occur at the head of their arguments,  which
are  written  as  a  list  enclosed  in  parentheses and separated by
commas, as with normal mathematical functions.

	e. g. CAR(U)
	      RPLACD(U,LIST(V))

Parentheses may be omitted if the operator is unary.

	e. g.  CAR Y and CAR(Y) are equivalent.

Such unary prefix operators have a precedence higher than  any  infix
operator.

	Infix operators may also be used in a prefix format on input.
On  output,  however,  they  will always be printed in infix form.

                                  6                                  


2.7 Strings

	Strings are used only in output statements. A string consists
of any number of characters enclosed in double quotes.

	e. g. "A STRING"


2.8 Comments

	Comments are useful for  including  explanatory  material  at
various points in a program.  They may be used in the following form:

  	COMMENT <any sequence of characters not including a terminator>
	        <terminator>
where
	 <terminator> ::= ;|$
	e. g. COMMENT THIS IS A COMMENT;

In addition, the sequence of symbols

  END <any sequence of symbols not including a  terminator,  a  right
       parenthesis or the reserved words END, ELSE or UNTIL>

is equivalent to the reserved word END.


2.9 Expressions

	REDUCE expressions may be of several  types  and  consist  of
syntactically  allowed  sequences  of  numbers, variables, operators,
left and right parentheses and commas.  The most common types are  as
follows:


2.9.1  Numerical Expressions

	These  consist  of  syntactically  allowed  combinations   of
integer  or real variables, arithmetic operators and parentheses, and
evaluate to numbers.

Examples:

	2
	I + J - 2 * I**2

are numerical expressions if I and J are integers.


2.9.2  Boolean Expressions

	These are expressions which return a truth value. In  REDUCE,
the  reserved  word  NIL represent the truth value 'false'. Any other
expression represents 'true'. So in a  sense,  any  expression  is  a
                                  7                                  


boolean  expression, because all expressions return a value. However,
a proper boolean expression has the syntactical form:

	<expression> <relational operator> <expression>
or
	<boolean expression> <logical operator> <boolean expression>
or
	NIL|T

They  are  used  mainly  in  the  IF  and FOR statements described in
Sections 2.12.2 and 2.12.3.

Examples:

        J<1
	3*X-1 >2
	U MEMBER V OR X=Y


2.9.3  Symbolic Expressions

	These consist of scalar variables and  operators  and  follow
the normal rules of the LISP meta language.

Examples:

	X
	CAR U . REVERSE V
	CDR(IF X=Y THEN X ELSE U)


2.9.4 Quoted Expressions

	Because  LISP  evaluation  requires  that  each  variable  or
expression have a value, it is necessary to add to REDUCE the concept
of a quoted expression by analogy with the LISP QUOTE function.  This
is provided by the single quote mark '.

	e. g. 'A    represents the LISP S-expression (QUOTE A)
	     '(A B C) represents the LISP S-expression (QUOTE (A B C))

Within a quoted expression, identifier  syntax  rules  are  those  of
REDUCE. Thus (A !. B) is the list consisting of the three elements A,
. and B, whereas (A . B) is the dotted pair of A and B.


2.9.5 LAMBDA Expressions

	LAMBDA  expressions  provide  the means for constructing LISP
LAMBDA expressions.
                                  8                                  


Syntax:

<LAMBDA expression> ::= LAMBDA <varlist><terminator><statement>
<varlist> ::= (<variable>,...,<variable>)

	e. g. LAMBDA (X,Y); CAR X . CDR Y

	is equivalent to the LISP LAMBDA expression

	(LAMBDA (X Y) (CONS (CAR X) (CDR Y)))

	The  parentheses  may  be  omitted in specifying the variable
list if desired.

	LAMBDA expressions may be used in symbolic mode in  place  of
prefix operators, or as an argument of the reserved word FUNCTION.


2.10 Reserved Words

	Certain  words  are reserved in REDUCE. They may only be used
in the manner described in this Manual. In particular, all the  infix
operators  introduced  in  Section  2.6  are  of  this type, plus the
statement and command names and other identifiers  in  the  following
list:

<reserved word> ::= BEGIN|DO|ELSE|END|FOR|FUNCTION|GO|GOTO|IF|LAMBDA|
			T|NIL|PRODUCT|RETURN|STEP|SUM|TO|UNTIL|WHILE|
			IN|OUT|ON|OFF|SHUT|WRITE


2.11 Statements

	A statement is any allowed combination of reserved words  and
expressions, and has the syntax

<statement> ::= <expression>|<proper statement>

	The following are some proper statements in REDUCE:


2.11.1 Assignment Statements

	These statements have the following syntax

<assignment statement> ::= <expression> := <statement>

	In symbolic mode, if the left side of an assignment statement
is a variable, a SETQ of the right hand side to that variable occurs.

	e. g.  X:=Y  translates into  (SETQ X Y).

	It is also possible to write an assignment in the form
                                  9                                  


<expression> := <expression> := ... := <expression> := <statement>

In this form, each <expression> is set to the value of the <statement>
by the right precedence grouping described in Section 2.6.


2.11.2 Conditional Statements

	The conditional statement has the following syntax:

<conditional statement> ::= IF <boolean expression> THEN <statement>
				 ELSE <statement>

Its use is obvious.  The ELSE clause is optional.

Conditional statements associate to the right; i.e., 

  IF <a> THEN <b> ELSE IF <c> THEN <d> ELSE <e>

is equivalent to:

  IF <a> THEN <b> ELSE (IF <c> THEN <d> ELSE <e>)

In addition, the construction

   IF <a> THEN IF <b> THEN <c> ELSE <d>

parses as

   IF <a> THEN (IF <b> THEN <c> ELSE <d>)


2.11.3 FOR Statements

	The FOR statement is used  to  define  a  program  loop.  Its
syntax is as follows:

    FOR <variable>:=<arithmetic expression> STEP <arithmetic expression>
      UNTIL <arithmetic expression> DO <statement>

	The FOR statement follows the normal ALGOL usage.  It returns
the value NIL.


2.11.4 WHILE Statements

	This  statement also defines a program loop. Its syntax is as
follows:

   WHILE <boolean statement> DO <statement>

	The  <boolean  statement>  is  first  tested.  If  true,  the
<statement> is executed and  the  process  then  repeated  until  the
<boolean statement> is false.
                                 10                                  


2.11.5 GO TO Statements

	GO  TO  (or  GOTO)  statements  are  used   to   perform   an
unconditional  transfer  to  a label in a compound statement (Section
2.11.6).  They have the syntax:

<go to statement> ::= GO TO <label>
<label> ::= <variable>

Restrictions:

GO TO statements may only occur within a compound statement. They may
NOT occur at the top level of your program.   Furthermore,  they  can
only  reference  labels  within  the  local  block  in which they are
defined.


2.11.6 Compound Statements

	A compound statement is defined by the following syntax

<compound statement> ::= BEGIN <compound tail>
<compound tail> ::= <unlabeled compound tail>
		    |<label>:<compound tail>
<unlabeled compound tail> ::= <statement> END 
		    | <statement> <terminator> <compound tail>
<label> ::= <identifier>
<terminator> ::= ;|$

	e. g. X :=  BEGIN INTEGER M;
			M:=1;
		    L1: IF N=0 THEN RETURN M;
			M:=M*N;
			N:=N-1;
			GO TO L1 
		    END OF BLOCK

will assign the factorial of a preassigned non-negative integer N to X.


2.11.7 RETURN Statements

	The RETURN statement allows for a transfer out of a  compound
statement  to  the next highest program level.  It may be used alone,
in which case the statement returns NIL.

	e. g.,	RETURN X+Y
		RETURN M
		RETURN

Restriction:

RETURN statements may only occur within a compound statement.They may
NOT occur at the top level of your program.
                                 11                                  


2.12 Declarations

	Declarations are a particular type of statement used  to  set
flags,  make  type  declarations  and  define  procedures.  PROCEDURE
declarations are  discussed  in  Section  2.15.   Some  other  REDUCE
declarations are as follows:


2.12.1 Variable Type Declarations

	These declarations tell the system  how  various  identifiers
are to be processed.  Types allowed include INTEGER, REAL and SCALAR.

	e. g.	INTEGER  M,N
		REAL M1
		SCALAR X,Y

Type  declarations  may  be made at any level in a program, and apply
only to the particular program block in which they occur.  They  MUST
however  immediately  follow  the BEGIN key-word if they are declared
within a block. Variables not declared are assumed SCALAR.   This  is
the basic algebraic variable type.


2.12.2 Array declarations

	Arrays in REDUCE are defined  similar  to  FORTRAN  dimension
statements.

	e. g. ARRAY  A(10),B(2,3,4)

Their  indices each range from 0 to the value declared. An element of
an array is referred to in standard FORTRAN notation,

	e. g. A(2)

All array elements are initialized to 0 at declaration time.

Array elements may appear in the left side of assignment statements.


2.12.3  Mode Handling Declarations

	Two  declarations  are  offered to the user for turning on or
off a variety of flags in the system.  The declarations  ON  and  OFF
take  a  list  of  flag  names  as  argument and turn them on and off
respectively.

	e. g.	ON ECHO
		OFF INT

	The  use  of  these flags and others available to the user is
explained later in this manual.

                                 12                                  


2.13 Commands

	A command is an order to the system to do something.  It  has
the syntax

<command> ::= <statement><terminator>|<proper command>

<proper command> ::= <command name><space>
			<statement>,...,<statement><terminator>

A variety of commands are discussed in the sections which follow.


2.14 File Handling Commands

	In  many  applications,  it  is  desirable to load previously
prepared REDUCE files into the system, or to write output on  varying
devices.   REDUCE offers three commands for this purpose, namely, IN,
OUT, and SHUT.


2.14.1 IN

	This command takes a list  of  file  names  as  argument  and
directs  the  system  to input each file (which should contain REDUCE
commands) into the system.   A file name will have a  varying  syntax
from  implementation  to implementation, but in many cases will be an
identifier.

	e. g.	IN F1,GGG; will load the files F1 and GGG.

	When input comes from an external file, statements are echoed
on the output device as they are  read.   If  this  facility  is  not
required, the echoing can be prevented by turning off  the flag  ECHO
in the relevant file.


2.14.2 OUT

	This  command  takes  a  single  file  name  as argument, and
directs output to that file from then on.  If the file has previously
been  used  for output during the current job, the output is appended
to the end of the file.  An existing file is erased before its  first
use for output in a job.

	To  output  on  the terminal without closing the output file,
the reserved file name T (for terminal) may be used.

	e. g. 	OUT OFILE; will direct output to the file OFILE and
		OUT T; will direct output the user's terminal.

                                 13                                  


2.14.3 SHUT

	This  command  is used to close an output file at completion.
Most systems require this action by the user, otherwise output may be
lost.    If  a  file is shut and a further OUT command issued for the
same file, the file is erased before the new output is written.


2.15 Procedures

	It  is  often  useful to name a statement for repeated use in
calculations  with  varying  parameters,  or  to  define   operators.
REDUCE  offers a procedural declaration for this purpose. Its general
syntax is:

	<procedural type> PROCEDURE <name><varlist>;<statement>;
with
	<varlist> ::= <empty>|(<variable>,...,<variable>)

or
	<procedural type>
	   PROCEDURE <variable> <binary infix name> <variable>;
	      <statement>;

The types permitted are REAL, INTEGER, SYMBOLIC, FEXPR and MACRO.

E. g., the example in Section 2.11.6 could  be  made  into  an integer
procedure FAC by the declaration:

	INTEGER PROCEDURE FAC (N);
		BEGIN INTEGER M;
			M:=1;
		    L1: IF N=0 THEN RETURN M;
			M:=M*N;
			N:=N-1;
			GO TO L1 
		END;

If we now evaluate FAC (3) we get the result 6.

	LISP function definitions may also be input in  a  procedural
form.  The  procedural type in this case is SYMBOLIC. For example, we
can define an association list searching function ASSOC as follows:

	SYMBOLIC PROCEDURE ASSOC(U,V);
	  IF NULL V THEN NIL
	   ELSE IF U=CAAR V THEN CAR V
	   ELSE ASSOC (U,CDR V);

	FEXPRs and MACROS may also be input in this manner  with  the
procedural types FEXPR and MACRO respectively.
                                 14                                  


	In  order  to allow users relatively easy access to the whole
REDUCE source program, system procedures are  not  protected  against
user redefinition.  If a procedure is redefined, a message

	*** <procedure name> REDEFINED

is printed.  If this occurs, and the user is not redefining  his  own
procedure, he is well advised to rename it!


2.16  Output of Strings

	It is often useful to write a title or comment on output,  or
name  output  expressions  in  a particular way.  This is possible in
REDUCE by means of the command WRITE.  The form of this command is

	WRITE <expression>,...,<expression>;

where <expression> may be either a symbolic expression  or  a  string
(Section  2.7). Strings are printed on output exactly as given except
for any characters which are ignored  by  the  input  scanner.  Other
expressions are evaluated and their value printed.

	The  print  line  is  closed  at the end of the WRITE command
evaluation.


2.17  Commands Used in Interactive Systems

	REDUCE is designed primarily for interactive use with a time-
shared computer, but  naturally  it  can  also  operate  in  a  batch
processing  environment.   There  is  a  basic  difference,  however,
between interactive and batch use of the system.  In the former case,
whenever  the  system  discovers  an  ambiguity  at  some  point in a
calculation, such as a forgotten type  assignment  for  instance,  it
asks  the user for the correct interpretation. In batch operation, it
is not practical to terminate the  calculation  at  such  points  and
require resubmission of the job, so the system makes the most obvious
guess of the user's intentions and continues the calculation.

	If  input  is coming from an external file, the system treats
it as a batch processed calculation.  If the user desires interactive
response  in  this  case,  he  can  turn on the flag INT in the file.
Likewise, he can turn off INT in the main  program  if  he  does  not
desire continual questioning from the system.

	Two commands are available in REDUCE for use  in  interactive
computing.   The  command  PAUSE;  may be inserted at any point in an
input file.  When this command is encountered on  input,  the  system
prints  the  message  CONT? on the user's terminal and halts.  If the
user responds Y (for yes), the calculation continues from that  point
in  the  file.   On  the other hand, if the user responds N (for no),
control  is  returned to the terminal, and the user can input further
commands. However, later on he can use the command CONT;, and control
                                 15                                  


is then transferred back to the point in  the  file  after  the  last
PAUSE was encountered.


2.18 END

	The command END; is used to end external files which are used
as  input  to REDUCE.  One of its purposes is to turn off the command
echo, which is annoying to a user typing at a terminal.  However,  it
also  does  some  file  control  book-keeping (for example, any files
still open are automatically closed), and  should  therefore  not  be
omitted.

	If  an  END  command  is used in the main program, control is
then transferred to LISP.


                                 16                                  


3. FUNCTIONS DEFINED IN REDUCE

	This  Section  gives the definitions of some of the functions
available  in REDUCE. The list is not complete; for example, it omits
all functions concerned with the scanning and parsing of  input.  The
definitions  of  the  latter  functions may be found by examining the
source of REDUCE.

	The  definitions  are divided into two main groups. First are
those functions which must be implemented at the machine or  assembly
language  level.  The  second group are those which can be defined in
terms of the basic set. In  the  latter  case,  the  complete  REDUCE
definition is included.


3.1 BASIC REDUCE FUNCTIONS

3.1.1 General Functions

%SYMBOLIC PROCEDURE ATOM(U);
  %Returns T if U is an atom, NIL otherwise;

%SYMBOLIC PROCEDURE CAR(U);
%Returns first half of dotted pair U.  Undefined for atoms;

%SYMBOLIC PROCEDURE CDR(U);
%Returns second half of dotted pair U.  Undefined for atoms;

%SYMBOLIC PROCEDURE COMPRESS(U);
  %Creates an atom (literal atom or number) from list of characters U,
  %adds it to the OBLIST if one exists, and returns the atom;

%SYMBOLIC PROCEDURE CONS(U,V);
   %Reclaims a free cell from the free storage list (or first calls the 
   %garbage collector if the free storage list is empty).
   %Returns the dotted pair of U and V as a pointer to the new cell;

%SYMBOLIC PROCEDURE EQ(U,V);
   %Returns T if U and V are identical objects (i.e., U and  V  point
   %to the same location), NIL otherwise.

%SYMBOLIC PROCEDURE ERROR(U);
   %Causes an error diagnostic to occur. The argument U is printed
   %and control then returns to the top level read-eval-print loop;

%SYMBOLIC PROCEDURE ERRORSET(U,V);
  %If an error occurs during the evaluation of U, NIL is returned. The
  %error message is printed if and only if V is T. If no error occurs,
  %LIST (!*EVAL(U)) is returned;

%SYMBOLIC PROCEDURE EXPLODE(U);
  %Returns a list of the constituent characters of atom U.  Must  also
  %work for integers. E.g., EXPLODE 123 = (1 2 3);
                                 17                                  


%FEXPR PROCEDURE FUNCTION(U);
  %Used with  constant  functional  arguments;

%SYMBOLIC PROCEDURE GENSYM();
  %Creates a new atom (e.g., G0123), adds it  to  the  OBLIST  if  one
  %exists, and returns the atom;

%SYMBOLIC PROCEDURE GETD(U);
  %Returns pointer to definition of U, if U is a  function  or  MACRO,
  %and NIL otherwise;

%FEXPR PROCEDURE GO(U);
   %Causes a transfer to label U;

%SYMBOLIC PROCEDURE ORDERP(U,V);
aaa%Used to test the order of objects according  to  their  location.
   %Returns T if U is ordered ahead of, or equal to V, NIL otherwise;

%SYMBOLIC PROCEDURE PUTD(NAME,VARLIS,BODY,TYPE);
  %Creates  a  function NAME, with variable list VARLIS and definition
  %BODY. TYPE is EXPR, FEXPR, or MACRO;

%SYMBOLIC PROCEDURE RETURN(U);
   %Causes return from a compound statement with value U;

%SYMBOLIC PROCEDURE RPLACA(U,V);
   %U  is  a  non-atomic  S-expression,  V  an  S-expression.  RPLACA
   %stores V in the CAR field of U and returns the modified U;

%SYMBOLIC PROCEDURE RPLACD(U,V);
   %U  is  a  non-atomic  S-expression,  V  an  S-expression.  RPLACD
   %stores V in the CDR field of U and returns the modified U;

%SYMBOLIC PROCEDURE STRINGP(U);
  %Returns T if U is a string, NIL otherwise;


3.1.2 Functions for Input and Output

%FEXPR PROCEDURE COMMENT(U);
   %Reads in the string U and acts like a <blank> to the scanner;

%SYMBOLIC PROCEDURE DIGIT(U);
  %Returns T if U is one of the digits 0 thru 9, NIL otherwise;

%SYMBOLIC PROCEDURE LITER(U);
  %Returns T if U is one of the letters A thru Z, NIL otherwise;

%SYMBOLIC PROCEDURE PRINC(U);
  %Adds the character string U to the output buffer.  Does  not  close
  %the print line.  Returns U;
                                 18                                  


%SYMBOLIC PROCEDURE PRIN1(U);
  %Adds  the character string  U  to the output buffer,  prefixing any
  %special characters with  an escape  character.   Does not close the
  %print line.  Returns U;

%SYMBOLIC PROCEDURE READCH();
  %Reads and returns one character from the input buffer;

%SYMBOLIC PROCEDURE TERPRI();
  %Prints the current contents of the  output buffer  and ends with an
  %EOR.  Prints a blank line if the buffer is empty;


3.1.3 Property List Functions

%SYMBOLIC PROCEDURE FLAG(U,V);
   %U is a list of literal atoms and V a literal atom.
   %Puts the flag V on the property list of each member of U;

%SYMBOLIC PROCEDURE FLAGP(U,V);
  %Returns  T if the atom U has flag V on its property list, otherwise
  %NIL;

%SYMBOLIC PROCEDURE GET(U,V);
   %U is a literal atom (not a number!).
   %Value is the property of U  whose  indicator  is  V  (or  NIL  if
   %indicator not present);

%SYMBOLIC PROCEDURE PUT(U,IND,PROP);
  %U and IND are literal atoms, PROP an S-expression.
  %Puts PROP on property list of U with indicator IND;

%SYMBOLIC PROCEDURE REMPROP(U,V);
   %U and V are literal atoms.
   %Removes property with indicator V from property list of U;

%SYMBOLIC PROCEDURE REMFLAG(U,V);
   %Removes the flag V from the property list of each member of U;


3.1.4 Arithmetic Functions

%SYMBOLIC PROCEDURE M**N;
   %M and N are integers or floating point numbers. Value is M**N;

%SYMBOLIC PROCEDURE FIX M;
  %Returns integer part of number M;

%SYMBOLIC PROCEDURE FIXP M;
   %Returns T is M is an integer, NIL otherwise;

%SYMBOLIC PROCEDURE M<N;
   %M and N are numbers. Returns T if M<N, NIL otherwise;
                                 19                                  


%SYMBOLIC PROCEDURE -M;
   %Returns negative of number M;

%SYMBOLIC PROCEDURE NUMBERP M;
   %Value is T if M is a number, NIL otherwise;

%SYMBOLIC PROCEDURE M+N;
   %Returns sum of numbers M and N;

%SYMBOLIC PROCEDURE M/N;
   %Returns quotient of numbers M and N;

%SYMBOLIC PROCEDURE /M;
   %Returns reciprocal of number M;

%SYMBOLIC PROCEDURE REMAINDER(M,N);
   %Returns remainder on dividing integer M by integer N;

%SYMBOLIC PROCEDURE M*N;
   %Returns product of numbers M and N;


3.1.5 Array Handling Functions

%SYMBOLIC PROCEDURE ARRAY(U);
  %Initializes arrays. Same definition as for SHARE  LISP  except that
  %'LIST' is omitted;

%SYMBOLIC PROCEDURE GETEL(U);
  %Returns array element U;

%SYMBOLIC PROCEDURE SETEL(U,V);
  %Sets array element U to V.  Returns V;


3.1.6 File Handling Functions

%SYMBOLIC PROCEDURE CLOSE(FILE);
  %Closes FILE  by   writing  appropriate   end-of-file  marks,   etc.
  %Returns FILE;

%SYMBOLIC PROCEDURE OPEN(FILE,STAT);
  %Opens a file named FILE on some external device.  STAT =  INPUT  or
  %OUTPUT. Returns FILE;

%SYMBOLIC PROCEDURE RDS(FILE);
  %Selects FILE as input device. All input now  comes  from  FILE.  If
  %FILE  is  NIL,  then the standard input device is selected. Returns
  %previous input file;

%SYMBOLIC PROCEDURE WRS(FILE);
  %Selects FILE as output device. All output now goes to FILE. If FILE
  %is NIL, then the standard output device is selected.  Returns prev-
  %ious input file;
                                 20                                  


3.1.7 Interpreter Functions

%SYMBOLIC PROCEDURE !*EVAL(U);
  %Evaluates expression U and returns value. If U is a  special  atom,
  %its special value is returned;

%SYMBOLIC PROCEDURE GTS(U);
  %Returns ('gets') the value of the special atom U;

%SYMBOLIC PROCEDURE PTS(U,V);
  %U is declared special if not already. PTS gives U the special value
  %V and returns V;


                                 21                                  


3.2 COMPOSITE REDUCE FUNCTIONS


SYMBOLIC PROCEDURE ABS M;
   IF M<0 THEN -M ELSE M;

FEXPR PROCEDURE AND U;
   BEGIN
    A:	IF NULL U THEN RETURN T
	 ELSE IF NOT !*EVAL CAR U THEN RETURN NIL;
	U := CDR U;
	GO TO A
   END;

SYMBOLIC PROCEDURE APPEND(U,V);
   IF NULL U THEN V ELSE CAR U . APPEND(CDR U,V);

SYMBOLIC PROCEDURE !*APPLY(U,V);
   !*EVAL(U . MAPCAR(V,FUNCTION MKQUOTE));

   SYMBOLIC PROCEDURE MKQUOTE U;
      LIST('QUOTE,U);

SYMBOLIC PROCEDURE ASSOC(U,V);
   IF NULL V THEN NIL
    ELSE IF U=CAAR V THEN CAR V
    ELSE ASSOC(U,CDR V);

SYMBOLIC PROCEDURE CAAAAR(X);
 CAR CAR CAR CAR X;

SYMBOLIC PROCEDURE CAAADR(X);
 CAR CAR CAR CDR X;

SYMBOLIC PROCEDURE CAAAR(X);
 CAR CAR CAR X;

SYMBOLIC PROCEDURE CAADAR(X);
 CAR CAR CDR CAR X;

SYMBOLIC PROCEDURE CAADDR(X);
 CAR CAR CDR CDR X;

SYMBOLIC PROCEDURE CAADR(X);
 CAR CAR CDR X;

SYMBOLIC PROCEDURE CAAR(X);
 CAR CAR X;

SYMBOLIC PROCEDURE CADAAR(X);
 CAR CDR CAR CAR X;

SYMBOLIC PROCEDURE CADADR(X);
 CAR CDR CAR CDR X;
                                 22                                  


SYMBOLIC PROCEDURE CADAR(X);
 CAR CDR CAR X;

SYMBOLIC PROCEDURE CADDAR(X);
 CAR CDR CDR CAR X;

SYMBOLIC PROCEDURE CADDDR(X);
 CAR CDR CDR CDR X;

SYMBOLIC PROCEDURE CADDR(X);
 CAR CDR CDR X;

SYMBOLIC PROCEDURE CADR(X);
 CAR CDR X;

SYMBOLIC PROCEDURE CDAAAR(X);
 CDR CAR CAR CAR X;

SYMBOLIC PROCEDURE CDAADR(X);
 CDR CAR CAR CDR X;

SYMBOLIC PROCEDURE CDAAR(X);
 CDR CAR CAR X;

SYMBOLIC PROCEDURE CDADAR(X);
 CDR CAR CDR CAR X;

SYMBOLIC PROCEDURE CDADDR(X);
 CDR CAR CDR CDR X;

SYMBOLIC PROCEDURE CDADR(X);
 CDR CAR CDR X;

SYMBOLIC PROCEDURE CDAR(X);
 CDR CAR X;

SYMBOLIC PROCEDURE CDDAAR(X);
 CDR CDR CAR CAR X;

SYMBOLIC PROCEDURE CDDADR(X);
 CDR CDR CAR CDR X;

SYMBOLIC PROCEDURE CDDAR(X);
 CDR CDR CAR X;

SYMBOLIC PROCEDURE CDDDAR(X);
 CDR CDR CDR CAR X;

SYMBOLIC PROCEDURE CDDDDR(X);
 CDR CDR CDR CDR X;

SYMBOLIC PROCEDURE CDDDR(X);
 CDR CDR CDR X;
                                 23                                  


SYMBOLIC PROCEDURE CDDR(X);
 CDR CDR X;

SYMBOLIC PROCEDURE DEFLIST(U,V);
   BEGIN SCALAR X;
    A:	IF NULL U THEN RETURN REVERSE X;
	PUT (CAAR U,V,CADAR U);
	X := CAAR U . X;
	U := CDR U;
	GO TO A
   END;

SYMBOLIC PROCEDURE DELETE(U,V);
   IF NULL V THEN NIL
    ELSE IF U=CAR V THEN CDR V
    ELSE CAR V . DELETE(U,CDR V);

SYMBOLIC PROCEDURE DIVIDE(M,N);
   (M/N) . REMAINDER(M,N);

SYMBOLIC PROCEDURE X=Y;
   IF ATOM X THEN IF NUMBERP X THEN NUMBERP Y AND X EQN Y
		   ELSE X EQ Y
    ELSE CAR X=CAR Y AND CDR X=CDR Y;

SYMBOLIC PROCEDURE M>=N;
   M=N OR M>N;

SYMBOLIC PROCEDURE M>N;
   NOT (M<=N);

SYMBOLIC PROCEDURE LENGTH U;
   IF NULL U THEN 0 ELSE LENGTH CDR U+1;

SYMBOLIC PROCEDURE M<=N;
   NOT(M>N);

FEXPR PROCEDURE LIST U;
   %Returns a list of elements in U;

SYMBOLIC PROCEDURE MAP(U,!*PI!*);
   BEGIN
   A:	IF NULL U THEN RETURN NIL;
	!*PI!* U;
	U := CDR U;
	GO TO A;
   END;

SYMBOLIC PROCEDURE MAPC(X,!*PI!*);
   BEGIN
    A:	IF NULL X THEN RETURN;
	!*PI!* CAR X;
	X := CDR X;
	GO TO A
                                 24                                  


   END;

SYMBOLIC PROCEDURE MAPCAR(X,!*PI!*);
 IF NULL X THEN NIL
  ELSE !*PI!* CAR X . MAPCAR(CDR X,!*PI!*);

SYMBOLIC PROCEDURE MAPCON(X,!*PI!*);
   IF NULL X THEN NIL
    ELSE NCONC(!*PI!* X,MAPCON(CDR X,!*PI!*));

SYMBOLIC PROCEDURE MAPLIST(X,!*PI!*);
 IF NULL X THEN NIL
  ELSE !*PI!* X . MAPLIST(CDR X,!*PI!*);

SYMBOLIC PROCEDURE MEMBER(X,Y);
 IF NULL Y THEN NIL
  ELSE IF X=CAR Y THEN T
  ELSE MEMBER(X,CDR Y);

SYMBOLIC PROCEDURE M-N;
   M+(-N);

SYMBOLIC PROCEDURE NCONC(U,V);
   BEGIN SCALAR W;
	IF NULL U THEN RETURN V;
	W := U;
    A:	IF NULL CDR W THEN GO TO B;
	W := CDR W;
	GO TO A;
    B:	RPLACD(W,V);
	RETURN U
   END;

SYMBOLIC PROCEDURE NOT U;
   U EQ NIL;

SYMBOLIC PROCEDURE NULL U;
   U EQ NIL;

FEXPR PROCEDURE OR(U);
   BEGIN
    A:	IF NULL U THEN RETURN NIL
	 ELSE IF !*EVAL CAR U THEN RETURN T;
	U := CDR U;
	GO TO A
   END;

SYMBOLIC PROCEDURE PAIR(U,V);
   BEGIN SCALAR X,Y,Z;
	X := U;
	Y := V;
    A:	IF NULL X THEN IF NULL Y THEN RETURN Z
	 ELSE ERROR LIST('PAIR,U,V);
	IF NULL Y THEN ERROR LIST('PAIR,U,V);
                                 25                                  


	Z := (CAR U . CAR V) . Z;
	X := CDR X;
	Y := CDR Y;
	GO TO A
   END;

SYMBOLIC PROCEDURE PRIN0 U;
   IF ATOM U THEN PRIN1 U
    ELSE BEGIN SCALAR V;
	V := U;
	PRINC "(";
    A:	PRIN0 CAR V;
	IF NULL CDR V THEN GO TO C
	 ELSE IF ATOM CDR V THEN GO TO B;
	PRINC " ";
	V := CDR V;
	GO TO A;
    B:	PRINC " . ";
	PRIN0 CDR V;
    C:	PRINC ")";
	RETURN U
    END;

SYMBOLIC PROCEDURE PRINT U;
   BEGIN PRIN0 U; TERPRI(); RETURN U END;

SYMBOLIC PROCEDURE PROG2(U,V);
   V;

FEXPR PROCEDURE QUOTE U;
   CAR U;

SYMBOLIC PROCEDURE READ();
   %Reads one S-expression from input;

SYMBOLIC PROCEDURE REVERSE(X);
 BEGIN SCALAR U,V;
	V := X;
  A:	IF NULL V THEN RETURN U;
	U := CAR V . U;
	V := CDR V;
	GO TO A;
 END;

SYMBOLIC PROCEDURE SASSOC(U,V,!*PI!*);
   IF NULL V THEN !*PI!*()
    ELSE IF U=CAAR V THEN CAR V
    ELSE SASSOC(U,CDR V,!*PI!*);

SYMBOLIC PROCEDURE SUBLIS(X,Y);
   BEGIN SCALAR U;
	IF NULL X THEN RETURN Y;
	U := X;
   A:	IF NULL U THEN RETURN IF ATOM Y
                                 26                                  


		OR (U := SUBLIS(X,CAR Y) . SUBLIS(X,CDR Y)) = Y
	     THEN Y
	    ELSE U
	 ELSE IF Y = CAAR U THEN RETURN CDAR U;
	U := CDR U;
	GO TO A
   END;

SYMBOLIC PROCEDURE SUBST(U,V,W);
   IF NULL W THEN NIL
    ELSE IF V=W THEN U
    ELSE IF ATOM W THEN W
    ELSE SUBST(U,V,CAR W).SUBST(U,V,CDR W);


                                 27                                  


4. FORMAL SYNTAX DEFINITION OF REDUCE

	The following is a definition of the syntax of  a  subset  of
REDUCE,  due  to R. Loos [4].  A more complete specification is under
development.


Meta notation: Terminals are headed by a quote mark
	       <    > denotes optionality
	       (    )* denotes 0 or more repetitions
	       / or (  /  ) denotes alternatives

r-def:	(type 'PROCEDURE id < '( (id ', )* ') > ';
	 / id '( (id ', )* ') ':= )  r-expr

type:	'LISP / 'SYMBOLIC / 'INTEGER / 'MACRO / 'FEXPR

id:	alphabetic / id (alphabetic/digit)*	

r-expr:	id ':= r-expr / disjunction

disjunction: conjunction / disjunction 'OR conjunction

conjunction: negation / conjunction 'AND negation

negation: relation / 'NOT negation

relation: term / term rel-op term

term:	factor / term plus-op factor

factor:	neg-pow / factor tim-op neg-pow

neg-pow: <'+ / '- > pow

pow:	dot-expr / pow '** dot-expr

dot-expr: primary / primary '. dot-expr

primary: constant / id / fn-call /'( r-expr ') /
	 'BEGIN (decl '; )* <label-stat ('; label-stat)*> <'; > 'END /
	 'IF r-expr 'THEN r-expr <'ELSE r-expr>

constant: integer / 'NIL / 'T / '' s-expr

integer: digit (digit)*  	

s-expr: id / <'-> integer / '( s-expr (s-expr)* <'. sexpr> ')

fn-call: id '( <r-expr (', r-expr)*> ') / id r-expr

decl:	('INTEGER / 'SCALAR ) id (', id)* 

label-stat: (id ': )* block-stat
                                 28                                  


block-stat: 'RETURN r-expr / ('GO 'TO /'GOTO ) id /
	'IF r-expr 'THEN block-stat <'ELSE block-stat> / r-expr

tim-op: '* / '/
plus-op: '+ / '-
rel-op:  '< / '<= / '= / 'NEQ / 'EQ  / '>= / '> / 'MEMBER 


                                 29                                  


                             REFERENCES

[1]  HEARN, A. C., REDUCE 2 User's Manual, Utah Computational Physics
     Group Memo No UCP-19, March 1973.

[2]  McCARTHY J., ABRAHAMS, P. W., EDWARDS. J., HART, T.  P.  and
     LEVIN, M. I., LISP 1.5 Programmer's Manual, M.I.T. Press, 1965

[3]  WEISSMAN, Clark, LISP 1.5 Primer, Dickenson, 1967

[4]  LOOS, R. G. K., Private Communication.

                                 30                                  


2.18 SOS-Link

	Facilities are present  in  REDUCE  to  allow  users  editing
access  to  program  source  files during calculations.  To use these
facilities, all function definitions should be input from SOS  files,
and  global changes to these files, such as renumbering and insertion
of page marks, should be avoided.

	There are two ways in which this link may be used.  These are
as follows:


2.18.1 Correction of Input Errors

	If an error is encountered on input  while  an  SOS  file  is
being  loaded,  the system will print the error diagnostics, and then
print the message EDIT?.  If the user types Y (for  yes), the  system
will  then  load  SOS and print the line which marks the beginning of
the command in which  the  error  occurred.  The  error  can  now  be
corrected.  After  editing  is complete, typing G (for go) in SOS has
the effect of closing the file, reloading your REDUCE core image, and
rereading  the input file from the beginning of the command where the
error occurred.


2.18.2 Editing Function Definitions

	Any functions which were input to REDUCE  from  an  SOS  file
have  information  saved  with them which tells the system where they
occur in the file (this is why global changes  to  the  source  files
should  be  avoided).  If  the  user  desires  to change the function
definition during an REDUCE calculation, he  can  access  the  source
definition in the file by typing

EDIT <function name>;

This  command  causes  SOS  to  be  loaded  and the first line of the
function printed.   The user can now edit  the  function  definition.
Typing G will cause the user's REDUCE program to be reloaded, and the
altered function definition to be read from the file.  Note, however,
that only one function may be redefined at a time by this method.


2.19 Debugging Facilities in REDUCE

	A few simple debugging facilities are available in REDUCE for
the more experienced programmer.  These are as follows:


2.19.1 Tracing Functions

	A command TR is available in REDUCE for tracing LISP function
calls.  This  command,  and  the  associated  commands UNTR, TRST and
UNTRST, are used in the form:
                                 31                                  


TR <function name>,<function name>,...,<function name>;

TR  calls  the  LISP function TRACE, and its output is in exactly the
same form. The trace may be turned off by  the  function  UNTR  which
uses the LISP function UNTRACE.

WARNING:
	Because  LISP establishes fast links to functions in compiled
code once that code has been referenced, it is necessary  to  inhibit
this  when  tracing  is  required.   TR  does  this  as  part  of its
evaluation sequence, but if tracing is not required until late  in  a
program,  the  fast links already established by then may nullify the
trace.  To prevent this, TR should be called with no arguments as the
first command in the program.


2.19.2 Tracing Assignments in Compound Statements

	Useful  diagnostic  information  can  often  be  obtained  by
observing  the  values  which variables acquire during assignments in
particular functions.  To do this in  REDUCE, one  uses  the  command
TRST.  There are some restrictions on the function names which appear
in the arguments of this function, however. First, the functions must
obviously  be  in  the system in symbolic form; compiled functions no
longer  contain  information  on  the  assignment   variable   names.
Secondly,  the  functions must have a compound statement at their top
level.

	This particular trace  may  be  turned  off  by  the  command
UNTRST.
                                 32                                  


3.  RUNNING REDUCE SYMBOLIC MODE ON THE STANFORD PDP-10

3.1	A  symbolic  mode version of REDUCE is stored as a 24K system
with filename RLISP.DMP.

	REDUCE may be loaded by typing R RLISP.  A message will  then
inform you when the program is loaded. The system then expects REDUCE
commands from you. You can return to LISP by the command END;

	If you require more core for your job,  you  can  get  it  by
typing

↑C
.CORE <size required><cr>
.ST<cr>

You will then be back in REDUCE.

Alternatively,  you can load the program initially with a larger core
size by typing

.R RLISP <core size><cr>

3.2 Special Features

3.2.1 If you give IN a variable  or  dotted  pair  as  argument,  the
system expects to find the file in your disk area, and similarly with
OUT. In addition, the reserved identifier L is used to represent  the
line printer on output.

	i. e. OUT L;

sends output to the line printer.

	Input from other devices may be specified  by  preceding  the
file name by the device name.  For example, to input a file ANDY from
disk area [S,JAM] followed by FOO from DTA2:, you would type

	IN (S,JAM),ANDY,DTA2!:,FOO;

3.2.2 The altmode character may be used as a terminator. This is very
convenient,  as  it  is not then necessary to follow it by a carriage
return as is required with the other terminators. However, the  value
of the symbolic evaluation is not printed in this case.

3.2.3 NOT

	The  character  ¬  may  be used interchangably with the unary
function NOT on input.  On output, however, NOT is printed.

3.3 A SAMPLE PROGRAM
                                 33                                  


.R RLISP				load the program

REDUCE 2 <system date>...		system loaded

*COMMENT A SAMPLE PROGRAM;		comments are allowed

*CAR ('(A));				compute the CAR of (A)

A					here's its value

*ASSOC(U,V):=IF NULL V THEN NIL		now define ASSOC
*	ELSE IF U≡ CAAR V THEN CAR V
*	ELSE ASSOC(U,CDR V);

*** ASSOC REDEFINED 			diagnostic message from REDUCE

ASSOC 					value from definition of ASSOC

*ASSOC ('A,'((B . C) (A . D)));		test ASSOC

(A . D)					it works!

*END;					return to LISP

***					value of END routine

ENTERING LISP...			so that you know
*